package xyz.syyrjx.filter;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import xyz.syyrjx.annotions.RequireLogin;
import xyz.syyrjx.annotions.Symbol;
import xyz.syyrjx.entity.ResultInfo;
import xyz.syyrjx.entity.User;
import xyz.syyrjx.service.RedisRemoteService;
import xyz.syyrjx.utils.JWTUtil;
import xyz.syyrjx.utils.RedisUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 登录拦截
 * @author Mr.Wan
 * @date 2022/10/12 - 20:17
 */
public class LoginFilter extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        RequireLogin requireLgoinAnnotion = handlerMethod.getMethodAnnotation(RequireLogin.class);
        //需要登录
        if (null == requireLgoinAnnotion){
            return true;
        }else{
            String token = JWTUtil.getToken(request);
            if (null == token){
                System.out.println("未登录");
                //没有登录
                return false;
            }
            ResultInfo<User> resultInfo = RedisUtil.getUser(token);
            if (!resultInfo.isFlag()){
                //登录失效
                System.out.println("登录失效");
                return false;
            }
            User user = resultInfo.getData();
            //获取角色、权限、连接符
            String[] authorities = requireLgoinAnnotion.authorities();
            String[] roles = requireLgoinAnnotion.roles();
            Symbol authoritiesRolesConnection = requireLgoinAnnotion.authoritiesRolesConnection();
            Symbol authoritiesConnection = requireLgoinAnnotion.authoritiesConnection();
            Symbol rolesConnection = requireLgoinAnnotion.rolesConnection();

            boolean authoritiesMeet = isMeet(user.getAuthorities(),authorities,authoritiesConnection);
            boolean rolesMeet = isMeet(user.getRoles(),roles,rolesConnection);

            //返回权限验证结果
            if (authoritiesRolesConnection.isAnd()){
                return authoritiesMeet & rolesMeet;
            }else{
                return authoritiesMeet | rolesMeet;
            }
        }

    }

    /**
     * 检查角色或权限是否满足
     * @param src 用户的权限或角色
     * @param target 需求的权限或角色
     * @param symbol 连接符
     * @return 如果满足要求返回true，反之返回false
     */
    private boolean isMeet(List<String> src, String[] target, Symbol symbol){
        //没有要求直接返回true
        if (null == target || 0 == target.length){
            return true;
        }
        if (symbol.isAnd() && target.length > src.size()){
            return false;
        }
        for (String t : target){
            //找到这个字符，要求为or，返回true
            if (src.contains(t)){
                if (!symbol.isAnd()){
                    return true;
                }
            }else{
                //没找到字符，要求全部满足，返回false；
                if (symbol.isAnd()){
                    return false;
                }
            }
        }
        //要求是and，到现在还没返回说明全部找到了，要求是or反之
        return symbol.isAnd();
    }


}
